package com.example.admin.pullrefresh;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.LinearInterpolator;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.view.ViewHelper;


public class PullRefreshLayout extends RelativeLayout implements AbsListView.OnScrollListener {

    //child
    private ListView child;
    //
    private boolean isTop = true;
    //
    private boolean mIsRecored = false;
    //child高度
    private int childHeight = 0;
    //头部View
    private View header;
    //太阳
    private ImageView sunny;
    //背景
    private ImageView bg;
    //最多可以下拉的高度
    private int height;
    //下拉高度越界
    float overstep = 0f;

    //按下的坐标
    private float down;
    //移动的坐标
    private float move;
    //抬起的坐标
    private float up;
    //阻力
    private float resistance = 0.5f;
    //动画时间
    private int duration = 1000;
    //是否正在刷新
    private boolean isRefresh = false;
    //刷新接口
    private OnRefresh onRefresh;


    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (childHeight <= 0) {
                childHeight = (int) msg.obj;
            }
        }
    };

    public PullRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    private void init() {
        Utils.isLog(true);
        //初始化头部；
        headerInit();


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


    }

    private void headerInit() {
        header = LayoutInflater.from(getContext()).inflate(R.layout.header, null, true);
        sunny = (ImageView) header.findViewById(R.id.sunny);
        bg = (ImageView) header.findViewById(R.id.re_bg);
        addView(header);
    }


    //可以在这里处理view的事件监听
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        child = (ListView) getChildAt(1);
        Message msg = handler.obtainMessage();
        msg.obj = child.getHeight();
        handler.sendMessage(msg);
        height = (int) (header.getHeight() / 1.5f);

        child.setOnScrollListener(this);

    }

    //事件分发
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                down = ev.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                move = ev.getRawY();
                if(isTop) {

                    if (move - down > ViewConfiguration.get(getContext()).getScaledTouchSlop()) {
                        return true;
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                up = ev.getRawY();
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    //触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                down = event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                move = event.getRawY();

                if (isRefresh) {
                    break;
                }
                float f = move - down;
                if (f < 0) {
                    down = event.getRawY();
                    break;
                }
                float h = height - f * resistance;

                //控制太阳的高度
                if (h < -30) {
                    h = -30;
                }
                ViewHelper.setTranslationY(sunny, h);
                //手势控制背景的缩放
                float scale = 1.05f + (h / height / 1.5f) * 0.3f;
                if (scale < 1) {
                    scale = 1;
                }
                ViewHelper.setScaleX(bg, scale);
                ViewHelper.setScaleY(bg, scale);

                if (h < 0) {
                    overstep = height + Math.abs(h) * 0.1f;
                } else {
                    overstep = height - h;
                }
                //手势控制child的位置
                ViewHelper.setTranslationY(child, overstep);
                setChildHeight((int) (childHeight - overstep));

                break;
            case MotionEvent.ACTION_UP:
                up = event.getRawY();
                if (isRefresh) {
                    break;
                }
                if (move - down > height * 2) {
                    stratAinm();
                } else {
                    ainmCancel();
                    endAinm();
                }
                break;
        }
        return true;
    }

    public void refreshOver() {
        ainmCancel();
        endAinm();
    }

    public void setRefresh(OnRefresh o) {
        onRefresh = o;
    }


    private AnimatorSet set;
    private ObjectAnimator soa1, soa2, boa1, boa2, coa;

    private void setSunnyAinm(float start, float end) {


        soa1 = ObjectAnimator.ofFloat(sunny, "TranslationY", start, end);
//        soa1.setDuration(duration);

        soa2 = ObjectAnimator.ofFloat(sunny, "Rotation", 0, 360);
        soa2.setRepeatCount(-1);
        soa2.setRepeatMode(ObjectAnimator.INFINITE);
        soa2.setInterpolator(new LinearInterpolator());
        soa2.setDuration(3000);

//        soa1.start();
//        soa2.start();
    }

    private void setBgAinm(float start, float end) {

        boa1 = ObjectAnimator.ofFloat(bg, "ScaleY", start, end);
//        boa1.setDuration(duration);

        boa2 = ObjectAnimator.ofFloat(bg, "ScaleX", start, end);
//        boa2.setDuration(duration);

//        boa1.start();
//        boa2.start();
    }

    private void setChildAinm(float start, float end) {
        coa = ObjectAnimator.ofFloat(child, "TranslationY", start, end);
//        coa.setDuration(duration);

    }


    private void setChildHeight(int h) {
        child.getLayoutParams().height = h;
        child.requestLayout();
    }


    private void setAinm() {
        if (set == null) {
            set = new AnimatorSet();
        }

        if (isRefresh) {
            set.play(soa1).with(boa1).
                    with(boa2).with(coa).before(soa2);
            set.start();
        } else {
            set.play(soa1).with(boa1).
                    with(boa2).with(coa);
            set.start();
        }

    }

    private void stratAinm() {
        isRefresh = true;
        setSunnyAinm(ViewHelper.getTranslationY(sunny), 0);
        setBgAinm(ViewHelper.getScaleX(bg), 1.05f);
        setChildAinm(ViewHelper.getTranslationY(child), height);
        setAinm();
        if (onRefresh != null) {
            onRefresh.refresh();
        }
    }

    private void endAinm() {
        isRefresh = false;
        setSunnyAinm(ViewHelper.getTranslationY(sunny), height / 1.5f);
        setBgAinm(ViewHelper.getScaleX(bg), 1.25f);
        setChildAinm(ViewHelper.getTranslationY(child), 0);
        setAinm();
        ValueAnimator va = ValueAnimator.ofInt(child.getHeight(), childHeight);
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

                setChildHeight((int) valueAnimator.getAnimatedValue());
            }
        });
        va.start();
    }

    public void ainmCancel() {
        if (set != null) {
            set.cancel();
            set = null;
        }
    }



    @Override
    public void onScrollStateChanged(AbsListView absListView, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int i2) {
        if (child.getChildCount() > 0 && child.getFirstVisiblePosition() == 0 && child.getChildAt(0).getTop() >= child.getPaddingTop()) {

            isTop = true;
        }
        else{
            isTop = false;
        }
        Utils.L("child.getChildCount():"+child.getChildCount());
        Utils.L("child.getFirstVisiblePosition():"+child.getFirstVisiblePosition());
        Utils.L("child.getChildAt(0).getTop():"+child.getChildAt(0).getTop());
        Utils.L("child.getPaddingTop():"+child.getPaddingTop());
    }

    public interface OnRefresh {

        public void refresh();
    }
}
